 
module top(
  input sys_clk,
  input key2,
  output led,
  
  //uart接口
  input uart_rxd,
  output uart_txd,

  //input cy_SCL,
  output cy_rst_out,
  inout [15:0] cyData,
  output cy_IFCLK_out                     ,
  input cy_to_fpga_CTL0_FLAGA        ,
  input cy_to_fpga_CTL2_FLAGC        ,
  input cy_to_fpga_CTL1_FLAGB        ,
  input cy_to_fpga_A7_FLAGD          ,
  output  cy_from_fpga_RDY1_SLWR       ,//output
  output  cy_from_fpga_RDY0_SLRD       ,//output
  input cy_A0_INT0                   ,
  output cy_A1_INT1                   ,
  output  cy_from_fpga_A2_SLOE         ,//output
  input cy_A3_WU2                    ,
  //output  cy_from_fpga_A4_FIFOADR0     ,//output
  output  cy_from_fpga_A5_FIFOADR1     ,//output
  //output  cy_from_fpga_A6_PKTEND       ,//output

  output w25q64_ncs,
  output w25q64_clk,
  inout w25q64_di_io0,
  inout w25q64_do_io1,
  inout w25q64_nwp_io2,
  inout w25q64_nhold_io3,
  
  //SDRAM 芯片接口
  output        sdram_clk_out,                //SDRAM 芯片时钟
  output        sdram_cke,                //SDRAM 时钟有效
  output        sdram_cs0_n,               //SDRAM 片选
  output        sdram_cs1_n,               //SDRAM 片选
  output        sdram_ras_n,              //SDRAM 行有效
  output        sdram_cas_n,              //SDRAM 列有效
  output        sdram_we_n,               //SDRAM 写有效
  output [ 1:0] sdram_ba,                 //SDRAM Bank地址
  output [12:0] sdram_addr,               //SDRAM 行/列地址
  inout  [15:0] sdram_data,               //SDRAM 数据
  output [ 1:0] sdram_dqm,                //SDRAM 数据掩码

  input hid_dat_n,
  input hid_clk_n,
  input hid_str_n,

  output audio_pwm,

  inout [7:0] ch375_d,
  input ch375_int,
  output ch375_a0,
  output ch375_cs,
  output ch375_rd,
  output ch375_wr,

  input   spi_MISO,        //     spi.MISO
  output  spi_MOSI,        //        .MOSI
  output  spi_SCLK,        //        .SCLK
  output  spi_CS,         //        .SS_n
 
  input flash_data0,
  output flash_sdo,
  output flash_sce,
  output flash_dclk,

  output ds1302_clk,
  inout  ds1302_dat,
  output ds1302_rst,
  
  output led_data_read,
  output led_data_write,
  output led_ins_read,

  // TMDS outputs
  output       TMDS_CLK,
  output [2:0] TMDS_DATA,

  input dummy
);

wire sys_rst_n;
assign sys_rst_n = key2 && locked_sdram && locked_cpu;
assign spirom_nwp_io2 = 1'b1;
assign spirom_nhold_io3 = 1'b1;


reg [31:0] cnt;
reg flg;
always @(posedge clk_cpu or negedge sys_rst_n) begin
  if (!sys_rst_n) begin
    cnt <= 0;
	 flg <= 0;
  end else begin
    cnt <= cnt+1'b1;
	 if(cnt==32'd50000000)begin
		cnt <= 0;
		flg <= ~flg;
	 end
  end
end




wire clk_100m;
wire clk_100m_shift;
wire clk_cpu;
wire locked_sdram;
wire locked_cpu;
//例化PLL, 产生各模块所需要的时钟
pll_clk u_pll_sdram(
  .areset				(~key2),
  .inclk0             (sys_clk),
  .c0                 (clk_100m),
  .c1                 (clk_100m_shift),
  .locked             (locked_sdram)
);

wire clk_cpu1;
wire clk_cpu2;
//例化PLL, 产生各模块所需要的时钟
pll_cpu u_pll_cpu(
  .areset	(~key2),
  .inclk0             (sys_clk),
  .c0                 (clk_cpu1),
  .c1                 (clk_cpu2),
	.locked             (locked_cpu)
);
wire cpu_clk_sel;
lpm_mux	LPM_MUX_component (
			.data ({clk_cpu2, clk_cpu1}),
			.sel (cpu_clk_sel),
			.result (clk_cpu)
			// synopsys translate_off
			,
			.aclr (),
			.clken (),
			.clock ()
			// synopsys translate_on
			);
defparam
	LPM_MUX_component.lpm_size = 2,
	LPM_MUX_component.lpm_type = "LPM_MUX",
	LPM_MUX_component.lpm_width = 1,
	LPM_MUX_component.lpm_widths = 1;
//myaltclkctrl myaltclkctrl_ins (
//.clkselect(cpu_clk_sel),
//.inclk0x(clk_cpu1),
//.inclk1x(clk_cpu2),
//.outclk(clk_cpu)
//);

//25Mhz
assign cy_IFCLK_out = clk_cy;
wire   cy_IFCLK_in  = ~clk_cy;
 
reg clk_cy;
always @(posedge sys_clk or negedge sys_rst_n) begin
  if (!sys_rst_n) begin
    clk_cy <= 0;
  end else begin
    clk_cy <= ~clk_cy;
  end
end

wire [31:0] outpin32;

wire [7:0] debug8;
wire [31:0] debug32;

wire hid_dat = ~hid_dat_n;
wire hid_clk = ~hid_clk_n;
wire hid_str = ~hid_str_n;

wire [15:0] video_rgb;

assign  sdram_clk_out = clk_100m_shift;//out_clk;                //将相位偏移时钟输出给sdram芯片

system 
#(
  .H_SYNC(11'd32), //行同步
  .H_BACK(11'd48), //行显示后沿
  .H_DISP(11'd1024),//行有效数据
  .H_TOTAL(11'd1184),  //行扫描周期 
  .V_SYNC(11'd4),  //场同步
  .V_BACK(11'd3),  //场显示后沿
  .V_DISP(11'd768),  //场有效数据
  .V_TOTAL(11'd790),  //场扫描周期
  .EXTRA_UP(11'd2),
  .EXTRA_DOWN(11'd2)
)system_inst(
  .clk      (clk_cpu),        //     clk_cpu
	.clk_50M  (sys_clk),
  .sdram_clk (clk_100m),
  .video_clk(pixclk),
 
  .reset_n  (sys_rst_n),  //   reset.reset_n

  //.mycpu_uart_rxd (uart_rxd), //        .uart_rxd
  //.mycpu_uart_txd (uart_txd), //   mycpu.uart_txd

  .debug8         (debug8),    //        .debug
  .debug32        (debug32),   //        .debug0

  .sdram_cke     (sdram_cke     ),   //        .ba
  .sdram_cs0_n    (sdram_cs0_n    ),   //        .cas_n
  .sdram_cs1_n    (sdram_cs1_n    ),   //        .cas_n
  .sdram_ras_n   (sdram_ras_n   ),   //        .cke
  .sdram_cas_n   (sdram_cas_n   ),   //        .cs_n
  .sdram_we_n    (sdram_we_n    ),   //        .dq
  .sdram_ba      (sdram_ba      ),   //        .dqm
  .sdram_addr    (sdram_addr    ),   //        .ras_n
  .sdram_data    (sdram_data    ),   //        .we_n
  .sdram_dqm     (sdram_dqm     ),

  .myuart_rxd     (uart_rxd),     //  myuart.rxd
  .myuart_txd     (uart_txd),      //        .txd

  .hid_clk   (hid_clk ),
  .hid_dat   (hid_dat ),
  .hid_str   (hid_str ),

  .softspi_MISO        (spi_MISO),        //     spi.MISO
  .softspi_MOSI        (spi_MOSI),        //        .MOSI
  .softspi_SCLK        (spi_SCLK),        //        .SCLK
  .softspi_CS          (spi_CS),         //        .SS_n    
  
  .flash_data0(flash_data0),
  .flash_sdo  (flash_sdo  ),
  .flash_sce  (flash_sce  ),
  .flash_dclk (flash_dclk ),

  .cyData(cyData),
  .cy_rst_out(cy_rst_out),
  //.cy_SDA(cy_SDA)       ,
  .cy_IFCLK(cy_IFCLK_in),
  .cy_to_fpga_CTL0_FLAGA(cy_to_fpga_CTL0_FLAGA),
  .cy_to_fpga_CTL2_FLAGC(cy_to_fpga_CTL2_FLAGC),
  .cy_to_fpga_CTL1_FLAGB(cy_to_fpga_CTL1_FLAGB),
  .cy_to_fpga_A7_FLAGD(cy_to_fpga_A7_FLAGD),
  .cy_from_fpga_RDY1_SLWR(cy_from_fpga_RDY1_SLWR)       ,//output
  .cy_from_fpga_RDY0_SLRD(cy_from_fpga_RDY0_SLRD)       ,//output
  .cy_from_fpga_A2_SLOE(cy_from_fpga_A2_SLOE)         ,//output
  .cy_A0_INT0(cy_A0_INT0)                   ,
  .cy_A1_INT1(cy_A1_INT1)                   ,
  .cy_A3_WU2(cy_A3_WU2)                    ,
  //.cy_from_fpga_A4_FIFOADR0(cy_from_fpga_A4_FIFOADR0)     ,//output
  .cy_from_fpga_A5_FIFOADR1(cy_from_fpga_A5_FIFOADR1)     ,//output
  //.cy_from_fpga_A6_PKTEND(cy_from_fpga_A6_PKTEND)       ,//output

  .audio_pwm (audio_pwm),
  
  .ch375_d      (ch375_d  ),
  .ch375_int    (ch375_int),
  .ch375_a0     (ch375_a0 ),
  .ch375_cs_out (ch375_cs ),
  .ch375_rd     (ch375_rd ),
  .ch375_wr     (ch375_wr ),


  .w25q64_ncs       (w25q64_ncs      ),
  .w25q64_do_io1    (w25q64_do_io1   ),
  .w25q64_nwp_io2   (w25q64_nwp_io2  ),
  .w25q64_nhold_io3 (w25q64_nhold_io3),
  .w25q64_clk       (w25q64_clk      ),
  .w25q64_di_io0    (w25q64_di_io0   ),
  
  .ds1302_clk       (ds1302_clk),
  .ds1302_dat       (ds1302_dat),
  .ds1302_rst       (ds1302_rst),
  
  .led_data_read         (led_data_read),
  .led_data_write        (led_data_write),
  .led_ins_read          (led_ins_read),

    .video_hs       (hsync),
    .video_vs       (vsync),
    .video_de       (video_de),
    .video_rgb      (video_rgb),

  .cpu_clk_sel (cpu_clk_sel),
  
  .dummy(dummy)
  
 );
 
wire [23:0] vdata = video_de ? {video_rgb[15:11],3'b0,video_rgb[10:5],2'b0,video_rgb[4:0],3'b0} : 24'd0;
 
 
assign led = led2;

reg led2;
reg [31:0] cnt2;
reg video_vs1;
always @(posedge pixclk or negedge sys_rst_n) begin
  if (!sys_rst_n) begin
    cnt2 <= 0;
    led2 <= 0;
  end else begin
    cnt2 <= cnt2 + 1'b1;
    if(cnt2==32'd25000000)begin
      cnt2 <= 0;
      led2 <= ~led2;
    end
  end
end

/*******************************************************************
Function for reversing the number of bits in a 10 bit parallel bus.
*******************************************************************/
function [10-1:0] bitOrder10 (input [10-1:0]  data);
integer i;
begin
   for (i=0; i < 10; i=i+1) begin : reverse
      bitOrder10[10-1-i] = data[i]; //Note how the vectors get swapped around here by the index. For i=0, i_out=15, and vice versa.
   end
end
endfunction

/*******************************************************************
Declare some internal wires.
*******************************************************************/
wire hsync, vsync, video_de;
wire pixclk;
wire [9:0] TMDS_red, TMDS_green, TMDS_blue;

/*******************************************************************
R, G, B TMDS encoder instances
*******************************************************************/ 
TMDS_encoder encode_R(.clk(pixclk), .VD( vdata[23:16] ), .CD(2'b00), .VDE(video_de), .TMDS(TMDS_red));
TMDS_encoder encode_G(.clk(pixclk), .VD( vdata[15:8] ), .CD(2'b00), .VDE(video_de), .TMDS(TMDS_green));
TMDS_encoder encode_B(.clk(pixclk), .VD( vdata[7:0] ), .CD({vsync, hsync}), .VDE(video_de), .TMDS(TMDS_blue));

/*******************************************************************
TMDS serializer of type ALTLVDS_TX
*******************************************************************/
serializer serializer_inst (
   .tx_in ({bitOrder10(TMDS_red), bitOrder10(TMDS_green), bitOrder10(TMDS_blue), 10'b0011111000} ),
   .tx_inclock ( sys_clk ),
   .tx_coreclock ( pixclk  ),
   .tx_out ( {TMDS_DATA, TMDS_CLK} )
   );
endmodule
